/**
  ******************************************************************************
  * File Name          : irkeytsk.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "bsp.h"
#include "tskcfg.h"
#include "irkey.h"
#include "gui.h"
#include <string.h>

TaskHandle_t xIrKey_Thd = NULL;
StaticTask_t xIrKey_Tcb;
StackType_t  xIrKey_Stk[IRKEY_STACK_SIZE];

static IrKey_WaveStru irkey_wave_bck;

static IrKey_KeyValueEnum irkey_wave_decode(const IrKey_WaveStru *wave)
{
  uint8_t i, j;
  uint32_t decode;

  for(i=0; i<irkey_wave_bck.cnt; i++)
  {
    if((irkey_wave_bck.ccr1[i] < IRKEY_WAVE_HEAD_PERIOD_RGMIN) || (irkey_wave_bck.ccr1[i] > IRKEY_WAVE_HEAD_PERIOD_RGMAX))
    {
      continue;
    }

    if((irkey_wave_bck.ccr2[i] < IRKEY_WAVE_HEAD_DUTY_RGMIN) || (irkey_wave_bck.ccr2[i] > IRKEY_WAVE_HEAD_DUTY_RGMAX))
    {
      continue;
    }

    j=i+1;
    if((irkey_wave_bck.cnt - j) < IRKEY_WAVE_EFFECCODE_LEN)
    {
      return IRKEY_KEY_VALUE_FAULT;
    }

    for(decode=0; j<IRKEY_WAVE_EFFECCODE_LEN+2; j++)
    {
      if((irkey_wave_bck.ccr2[j] < IRKEY_WAVE_BIT_DUTY_RGMIN) || (irkey_wave_bck.ccr2[j] > IRKEY_WAVE_BIT_DUTY_RGMAX))
      {
        return IRKEY_KEY_VALUE_FAULT;
      }

      if((irkey_wave_bck.ccr1[j] >= IRKEY_WAVE_BIT_PERIOD0_RGMIN) && (irkey_wave_bck.ccr1[j] <= IRKEY_WAVE_BIT_PERIOD0_RGMAX))
      {
        decode <<= 1;
      }
      else if((irkey_wave_bck.ccr1[j] >= IRKEY_WAVE_BIT_PERIOD1_RGMIN) && (irkey_wave_bck.ccr1[j] <= IRKEY_WAVE_BIT_PERIOD1_RGMAX))
      {
        decode <<= 1;
        decode |= 1;
      }
      else
      {
        return IRKEY_KEY_VALUE_FAULT;
      }
    }
    
    switch(decode)
    {
      case IRKEY_CODE_OK:
        return IRKEY_KEY_VALUE_OK;
      
      case IRKEY_CODE_ENTER:
        return IRKEY_KEY_VALUE_ENTER;
      
      case IRKEY_CODE_UP:
        return IRKEY_KEY_VALUE_UP;
      
      case IRKEY_CODE_DOWN:
        return IRKEY_KEY_VALUE_DOWN;
      
      case IRKEY_CODE_LEFT:
        return IRKEY_KEY_VALUE_LEFT;
      
      case IRKEY_CODE_RIGHT:
        return IRKEY_KEY_VALUE_RIGHT;
      
      case IRKEY_CODE_RETURN:
        return IRKEY_KEY_VALUE_RETURN;
      
      case IRKEY_CODE_MENU:
        return IRKEY_KEY_VALUE_MENU;
      
      case IRKEY_CODE_SET:
        return IRKEY_KEY_VALUE_SET;
      
      case IRKEY_CODE_HOME:
        return IRKEY_KEY_VALUE_HOME;
      
      case IRKEY_CODE_1:
        return IRKEY_KEY_VALUE_1;
      
      case IRKEY_CODE_2:
        return IRKEY_KEY_VALUE_2;
      
      case IRKEY_CODE_3:
        return IRKEY_KEY_VALUE_3;
      
      case IRKEY_CODE_4:
        return IRKEY_KEY_VALUE_4;
      
      case IRKEY_CODE_5:
        return IRKEY_KEY_VALUE_5;
      
      case IRKEY_CODE_6:
        return IRKEY_KEY_VALUE_6;
      
      case IRKEY_CODE_7:
        return IRKEY_KEY_VALUE_7;
      
      case IRKEY_CODE_8:
        return IRKEY_KEY_VALUE_8;
      
      case IRKEY_CODE_9:
        return IRKEY_KEY_VALUE_9;
      
      case IRKEY_CODE_0:
        return IRKEY_KEY_VALUE_0;
      
      case IRKEY_CODE_VOLINC:
        return IRKEY_KEY_VALUE_VOLINC;
      
      case IRKEY_CODE_VOLDEC:
        return IRKEY_KEY_VALUE_VOLDEC;
      
      case IRKEY_CODE_MUTE:
        return IRKEY_KEY_VALUE_MUTE;
      
      case IRKEY_CODE_POWER:
        return IRKEY_KEY_VALUE_POWER;
      
      case IRKEY_CODE_T:
        return IRKEY_KEY_VALUE_T;
      
      default:
        return IRKEY_KEY_VALUE_FAULT;
    }
  }
  
  return IRKEY_KEY_VALUE_FAULT;
}

void vIrKey_Task(void * pvParameters)
{
  TickType_t delay;
  IrKey_KeyValueEnum code, code_last;
  uint16_t kcnt;
  Gui_CmdQueStru scmd;
  
  irkey_init();
  
  code = IRKEY_KEY_VALUE_FAULT;
  code_last = IRKEY_KEY_VALUE_FAULT;
  kcnt = 0;
  delay = portMAX_DELAY;

  while(1)
  {
    if(xQueueReceive(irkey_wave_qhd, &irkey_wave_bck, delay) == pdTRUE)
    {
      code = irkey_wave_decode(&irkey_wave_bck);
//      irkey_debug("key RECV\r\n");
      if(code == IRKEY_KEY_VALUE_FAULT)
      {
        kcnt = 0;
        delay = portMAX_DELAY;
//        irkey_debug("key FAULT\r\n");
        continue;
      }
      
      if(code != code_last)
      {
        kcnt = 0;
      }

      code_last = code;
      if(kcnt++ > 5)
      {
        kcnt = 0;
        scmd.cmd = GUI_CMD_KEY;
        scmd.key = code;
        scmd.toform = NULL;
        xQueueSend(gui_cmd_qhd, &scmd, 5);
//        irkey_debug("key:%u\r\n", code);
      }
      
      delay = 70;
    }
    else
    {
      scmd.cmd = GUI_CMD_KEY;
      scmd.key = code;
      scmd.toform = NULL;
      xQueueSend(gui_cmd_qhd, &scmd, 5);
//      irkey_debug("key_T:%u\r\n", code);

      code = IRKEY_KEY_VALUE_FAULT;
      code_last = IRKEY_KEY_VALUE_FAULT;
      kcnt = 0;
      delay = portMAX_DELAY;
    }
  }
}
